[em construção…]

Download dos dados e conversão do formato

No chunk abaixo rodamos um procedimento de busca e coleta da base de dados completa das exportações e importações nacionais no período compreendido entre jan/1997 até o último mês disponível. Ao rodar o chunk a cada mês ele atualiza os arquivos, (se houver nova publicação no SECEX) sem a necessidade de baixá-los do site toda vez.

Descomente o chunk (retirando as cerquilhas) onde os comandos estão presentes caso queira reproduzir na sua máquina ou adapte para setar um outro repositório para armazenar os arquivos.

#Baixa a serie completa
#url_exp <- download.file("http://www.mdic.gov.br/balanca/bd/comexstat-bd/ncm/EXP_COMPLETA.zip") #Exportacoes
#url_imp <- download.file("http://www.mdic.gov.br/balanca/bd/comexstat-bd/ncm/IMP_COMPLETA.zip") #Importacoes

#Escrevo num local temporario
#temp_exp <- tempfile()
#temp_imp <- tempfile()

#Insiro os arquivos .zip na pasta local temporaria
#download.file(url_exp, temp_exp)
#download.file(url_imp, temp_imp)

#Deszipa os arquivos
#unzip_exp <- unz(temp_exp, "EXP_COMPLETA.csv") #Extrai as exportacoes na base completa
#unzip_imp <- unz(temp_imp, "IMP_COMPLETA.csv") #Extrai as importacoes na base completa

Após guardá-lo em um determinado local estipule uma rotina de em determinado dia do mês rodar o chunk acima para atualizar os arquivos da base completa.

Você poderá atualizar os arquivos quando criar um modelo de visualização de dados (assim como eu fiz uma usando o Power BI no final deste documento) sem se preocupar em reorganizá-los ou fazer o procedimento todo novamente.

Isso lhe fornece velocidade e minimiza substancialmente quaisquer erros humanos no processo.

Neste tutorial, trabalho com um ETL menor para os dados de exportação disponível no último mês, como demonstração. Utilizo a linguagem R aqui dentro de um documento do tipo RMarkdown para elucidar mais claramente as nossas possibilidades.

Pauta de Exportações

Primeiro baixo os dados de exportação:

#expdwnld<-download.file("http://www.mdic.gov.br/balanca/bd/comexstat-bd/ncm/EXP_2020.csv", "exp.csv")
exp<-read.csv("exp.csv", head=TRUE, sep=";", encoding = "latin1")

head(exp)
  CO_ANO CO_MES   CO_NCM CO_UNID CO_PAIS SG_UF_NCM CO_VIA  CO_URF QT_ESTAT
1   2020      6 22030000      17     607        PA      0  217800       12
2   2020      2 39269090      10      63        PR      1  817800       81
3   2020      8 84149039      10     158        SP      7 1017500       66
4   2020      8 84198999      11     589        SP      4  817700        1
5   2020      4  7094000      10     580        AL      0  417900        5
6   2020     11 21031090      10      97        SP      7  147600     5867
  KG_LIQUIDO VL_FOB
1         12    218
2         81    797
3         66   4853
4         15    520
5          5     16
6       5867   5947
#library(vctrs)
library(dplyr)
glimpse(exp)
Rows: 647,595
Columns: 11
$ CO_ANO     <int> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 20...
$ CO_MES     <int> 6, 2, 8, 8, 4, 11, 7, 7, 3, 11, 9, 2, 5, 8, 3, 3, 11, 1,...
$ CO_NCM     <int> 22030000, 39269090, 84149039, 84198999, 7094000, 2103109...
$ CO_UNID    <int> 17, 10, 10, 11, 10, 10, 10, 10, 11, 10, 10, 10, 10, 10, ...
$ CO_PAIS    <int> 607, 63, 158, 589, 580, 97, 467, 434, 158, 163, 434, 434...
$ SG_UF_NCM  <chr> "PA", "PR", "SP", "SP", "AL", "SP", "PR", "SP", "SP", "E...
$ CO_VIA     <int> 0, 1, 7, 4, 0, 7, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 12, 4, 4...
$ CO_URF     <int> 217800, 817800, 1017500, 817700, 417900, 147600, 917800,...
$ QT_ESTAT   <dbl> 12, 81, 66, 1, 5, 5867, 3, 28, 1, 350, 2, 98, 1, 2, 150,...
$ KG_LIQUIDO <dbl> 12, 81, 66, 15, 5, 5867, 3, 25, 0, 350, 2, 98, 1, 2, 46,...
$ VL_FOB     <int> 218, 797, 4853, 520, 16, 5947, 7, 618, 18, 403, 125, 190...

Agregando por mês/ano

Concateno CO_ANO com CO_MES

library(tidyverse)

exp<-exp%>%
  mutate(CO_MES = formatC(CO_MES, width = 2, flag = "0")) #Arrumo pra dois digitos no mes

library(lubridate)

exp$AnoMes<-str_c(exp$CO_ANO,"/",exp$CO_MES) #uno uma coluna com a outra e chamo ela de MesAno

glimpse(exp)
Rows: 647,595
Columns: 12
$ CO_ANO     <int> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 20...
$ CO_MES     <chr> "06", "02", "08", "08", "04", "11", "07", "07", "03", "1...
$ CO_NCM     <int> 22030000, 39269090, 84149039, 84198999, 7094000, 2103109...
$ CO_UNID    <int> 17, 10, 10, 11, 10, 10, 10, 10, 11, 10, 10, 10, 10, 10, ...
$ CO_PAIS    <int> 607, 63, 158, 589, 580, 97, 467, 434, 158, 163, 434, 434...
$ SG_UF_NCM  <chr> "PA", "PR", "SP", "SP", "AL", "SP", "PR", "SP", "SP", "E...
$ CO_VIA     <int> 0, 1, 7, 4, 0, 7, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 12, 4, 4...
$ CO_URF     <int> 217800, 817800, 1017500, 817700, 417900, 147600, 917800,...
$ QT_ESTAT   <dbl> 12, 81, 66, 1, 5, 5867, 3, 28, 1, 350, 2, 98, 1, 2, 150,...
$ KG_LIQUIDO <dbl> 12, 81, 66, 15, 5, 5867, 3, 25, 0, 350, 2, 98, 1, 2, 46,...
$ VL_FOB     <int> 218, 797, 4853, 520, 16, 5947, 7, 618, 18, 403, 125, 190...
$ AnoMes     <chr> "2020/06", "2020/02", "2020/08", "2020/08", "2020/04", "...
colSums(is.na(exp)) #Conta quantos missings temos em cada variavel
    CO_ANO     CO_MES     CO_NCM    CO_UNID    CO_PAIS  SG_UF_NCM     CO_VIA 
         0          0          0          0          0          0          0 
    CO_URF   QT_ESTAT KG_LIQUIDO     VL_FOB     AnoMes 
         1          1          1          1          0 

Agrego por período e organizo de modo decrescente temporalmente:

expper<-exp%>%
  group_by(AnoMes)%>%
  summarise(Total_AnoMes =sum(VL_FOB, na.rm = TRUE))

arrange(expper, AnoMes)
# A tibble: 11 x 2
   AnoMes  Total_AnoMes
   <chr>          <dbl>
 1 2020/01   7202769125
 2 2020/02   7999455705
 3 2020/03  10131953733
 4 2020/04  10469768607
 5 2020/05   9170526194
 6 2020/06  10554344215
 7 2020/07   8919268283
 8 2020/08   7929470790
 9 2020/09  10437232948
10 2020/10  10173525205
11 2020/11   9914809207

Vamos ver num gráfico:

library(plotly)
library(ggplot2)

ggplotly(ggplot(expper, aes(x=AnoMes, y=Total_AnoMes))+
  geom_bar(stat="identity")+
  theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)))

Agregando por NCM

Baixo os dados de código NCM e nome

#ncmdwlnd<-download.file("http://www.mdic.gov.br/balanca/bd/tabelas/NCM.csv","NCM.csv")
ncm <- read.csv("NCM.csv", sep = ";", encoding = "latin1")

glimpse(ncm)
Rows: 13,117
Columns: 14
$ CO_NCM         <int> 29398000, 30021100, 30021211, 30021212, 30021213, 30...
$ CO_UNID        <int> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, ...
$ CO_SH6         <int> 293980, 300211, 300212, 300212, 300212, 300212, 3002...
$ CO_PPE         <int> 3329, 3990, 3990, 3990, 3990, 3990, 3990, 3990, 3990...
$ CO_PPI         <int> 3329, 3221, 3990, 3990, 3990, 3990, 3990, 3990, 3990...
$ CO_FAT_AGREG   <int> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3...
$ CO_CUCI_ITEM   <chr> "54149", "54163", "54163", "54163", "54163", "54163"...
$ CO_CGCE_N3     <int> 240, 322, 322, 322, 322, 322, 322, 322, 322, 322, 32...
$ CO_SIIT        <int> 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000...
$ CO_ISIC_CLASSE <int> 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100...
$ CO_EXP_SUBSET  <int> 1402, 1406, 1406, 1406, 1406, 1406, 1406, 1406, 1406...
$ NO_NCM_POR     <chr> "Outros alcalóides, naturais ou reproduzidos por sín...
$ NO_NCM_ESP     <chr> "Otros alcaloides, naturales o producidas por síntes...
$ NO_NCM_ING     <chr> "Other alkaloids, natural or produced by synthesis, ...

Então agrupo as exportações (em US$ FOB) por NCM: (O agruoamento é necessário por uma questão de limitação de processamento e memória)

#agrupa exp por ncm
expncm<-exp%>%
  group_by(CO_NCM)%>%
  summarise(Total_NCM = sum(VL_FOB, na.rm=TRUE))%>%
  mutate(NCM_percentual = (Total_NCM/sum(Total_NCM))*100)


options(scipen = 999) #nao mostra os numeros em notacao cientifica
arrange(expncm, desc(Total_NCM))
# A tibble: 7,221 x 3
     CO_NCM   Total_NCM NCM_percentual
      <int>       <dbl>          <dbl>
 1 12019000 14629728205          14.2 
 2 26011100 13646169071          13.3 
 3 27090010 10539296149          10.2 
 4  2023000  3400566270           3.30
 5 17011400  3241461371           3.15
 6 10059010  2978570679           2.89
 7 47032900  2676864839           2.60
 8  9011110  2471400955           2.40
 9 23040090  2243753258           2.18
10  2071400  2029716733           1.97
# ... with 7,211 more rows

Caso os nomes dos produtos pelo NCM:

library(tidyverse)
expncm <- left_join(expncm, ncm %>%
                             select(CO_NCM, NO_NCM_POR), by = c("CO_NCM" = "CO_NCM"))%>%
                             mutate(TotExpNCM = expncm$Total_NCM)
expncm<-expncm%>%
  select(-Total_NCM) #tiro fora a soma pra nao ficar em duplicidade

glimpse(expncm)
Rows: 7,221
Columns: 4
$ CO_NCM         <int> 1012100, 1012900, 1019000, 1022110, 1022190, 1022919...
$ NCM_percentual <dbl> 0.001101809115016, 0.000525771209761, 0.000000018463...
$ NO_NCM_POR     <chr> "Cavalos reprodutores de raça pura", "Cavalos, excet...
$ TotExpNCM      <dbl> 1133796, 541035, 19, 9158, 8800, 47321, 128990607, 5...

Vamos ver como fica a classificação:

arrange(expncm,desc(TotExpNCM))
# A tibble: 7,221 x 4
    CO_NCM NCM_percentual NO_NCM_POR                                   TotExpNCM
     <int>          <dbl> <chr>                                            <dbl>
 1  1.20e7          14.2  Soja, mesmo triturada, exceto para semeadura   1.46e10
 2  2.60e7          13.3  Minérios de ferro e seus concentrados, exce~   1.36e10
 3  2.71e7          10.2  Óleos brutos de petróleo                       1.05e10
 4  2.02e6           3.30 Carnes desossadas de bovino, congeladas        3.40e 9
 5  1.70e7           3.15 Outros açúcares de cana                        3.24e 9
 6  1.01e7           2.89 Milho em grão, exceto para semeadura           2.98e 9
 7  4.70e7           2.60 Pastas químicas de madeira, à soda ou ao su~   2.68e 9
 8  9.01e6           2.40 Café não torrado, não descafeinado, em grão    2.47e 9
 9  2.30e7           2.18 Bagaços e outros resíduos sólidos, da extra~   2.24e 9
10  2.07e6           1.97 Pedaços e miudezas, comestíveis de galos/ga~   2.03e 9
# ... with 7,211 more rows

Podemos filtrar aqueles que possuem a string “soja” no nome do produto (NCM):

expncmsoja<-expncm%>%
  filter(grepl("soja", NO_NCM_POR ) | grepl("Soja", NO_NCM_POR))

arrange(expncmsoja, desc(NCM_percentual))
# A tibble: 12 x 4
    CO_NCM NCM_percentual NO_NCM_POR                                   TotExpNCM
     <int>          <dbl> <chr>                                            <dbl>
 1  1.20e7     14.2       Soja, mesmo triturada, exceto para semeadura   1.46e10
 2  2.30e7      2.18      Bagaços e outros resíduos sólidos, da extra~   2.24e 9
 3  2.30e7      0.530     Farinhas e pellets, da extração do óleo de ~   5.45e 8
 4  1.51e7      0.306     Óleo de soja, em bruto, mesmo degomado         3.15e 8
 5  1.51e7      0.0769    Óleo de soja, refinado, em recipientes com ~   7.91e 7
 6  3.50e7      0.00742   Proteínas de soja em pó, com teor de proteí~   7.64e 6
 7  1.51e7      0.00640   Óleo de soja, refinado, em recipientes com ~   6.58e 6
 8  2.10e7      0.000544  Molho de soja, preparado, em embalagens ime~   5.59e 5
 9  1.20e7      0.000302  Soja, mesmo triturada, para semeadura          3.11e 5
10  1.21e7      0.000196  Farinha de soja                                2.02e 5
11  2.10e7      0.000166  Outros molhos de soja, preparados              1.71e 5
12  1.51e7      0.0000447 Outros óleos de soja                           4.60e 4

Ou então poderíamos filtrar com base em diferentes strings de produtos:

expncmprodutos<-expncm%>%
  filter(grepl("soja", NO_NCM_POR ) | grepl("Soja", NO_NCM_POR) |
         grepl("milho", NO_NCM_POR ) | grepl("Milho", NO_NCM_POR) |
         grepl("açúcar", NO_NCM_POR ) | grepl("Açúcar", NO_NCM_POR))

arrange(expncmprodutos,desc(NCM_percentual))
# A tibble: 85 x 4
    CO_NCM NCM_percentual NO_NCM_POR                                   TotExpNCM
     <int>          <dbl> <chr>                                            <dbl>
 1  1.20e7         14.2   Soja, mesmo triturada, exceto para semeadura   1.46e10
 2  1.70e7          3.15  Outros açúcares de cana                        3.24e 9
 3  1.01e7          2.89  Milho em grão, exceto para semeadura           2.98e 9
 4  2.30e7          2.18  Bagaços e outros resíduos sólidos, da extra~   2.24e 9
 5  1.70e7          0.615 Outros açúcares de cana, beterraba, sacaros~   6.33e 8
 6  2.30e7          0.530 Farinhas e pellets, da extração do óleo de ~   5.45e 8
 7  1.51e7          0.306 Óleo de soja, em bruto, mesmo degomado         3.15e 8
 8  2.01e7          0.268 Suco (sumo) de laranja, não fermentados, se~   2.76e 8
 9  2.01e7          0.148 Outros sucos de laranjas, não fermentados, ~   1.52e 8
10  2.01e7          0.147 Suco (sumo) de laranja, não fermentados, se~   1.51e 8
# ... with 75 more rows

Você poderia exportar esta tabela filtrada para um arquivo do tipo .csv:

write.csv(expncmprodutos, "expncmprodutos.csv")

Poderíamos calcular uma estimativa de participação neste ano de 2020 da lista de nossos produtos exportados em relação ao total exportado pelo Brasil fazendo:

round((sum(expncmprodutos$TotExpNCM, na.rm=TRUE)/sum(expncm$TotExpNCM, na.rm=TRUE))*100,digits = 2) 
 24.76

Ou seja, cerca de 24.76% dos nossos produtos tiveram representatividade na pauta exportadora brasileira de janeiro até o último mês disponível na base de 2020.

Finalmente eu crio a tabela com somente os 10 primeiros produtos exportados no Brasil, por ordem de valor em dólares FOB:

topten<-expncm%>%
  top_n(TotExpNCM, n=10)

arrange(topten, desc(TotExpNCM))
# A tibble: 10 x 4
    CO_NCM NCM_percentual NO_NCM_POR                                   TotExpNCM
     <int>          <dbl> <chr>                                            <dbl>
 1  1.20e7          14.2  Soja, mesmo triturada, exceto para semeadura   1.46e10
 2  2.60e7          13.3  Minérios de ferro e seus concentrados, exce~   1.36e10
 3  2.71e7          10.2  Óleos brutos de petróleo                       1.05e10
 4  2.02e6           3.30 Carnes desossadas de bovino, congeladas        3.40e 9
 5  1.70e7           3.15 Outros açúcares de cana                        3.24e 9
 6  1.01e7           2.89 Milho em grão, exceto para semeadura           2.98e 9
 7  4.70e7           2.60 Pastas químicas de madeira, à soda ou ao su~   2.68e 9
 8  9.01e6           2.40 Café não torrado, não descafeinado, em grão    2.47e 9
 9  2.30e7           2.18 Bagaços e outros resíduos sólidos, da extra~   2.24e 9
10  2.07e6           1.97 Pedaços e miudezas, comestíveis de galos/ga~   2.03e 9

Tentando interagir com esse treemap:

library(highcharter)

tmap <- expncm %>%
  hchart(
    "treemap", 
    hcaes(x = NO_NCM_POR, value = TotExpNCM, color = TotExpNCM)
    )

tmap

Agregando por UF

Provavelmente o estado que mais exporta deverá ser o de São Paulo. Vamos verificar em quanto:

expuf<-exp%>%
  group_by(SG_UF_NCM)%>%
  summarise(TotalExp_UF = sum(VL_FOB, na.rm = TRUE))%>%
            mutate(ExpUFpercentual = (TotalExp_UF/sum(TotalExp_UF))*100)

arrange(expuf, desc(TotalExp_UF))
# A tibble: 28 x 3
   SG_UF_NCM TotalExp_UF ExpUFpercentual
   <chr>           <dbl>           <dbl>
 1 SP        19286741880           18.7 
 2 MG        12758488329           12.4 
 3 RJ        12209866459           11.9 
 4 PA        11265073687           10.9 
 5 MT         9076020707            8.82
 6 PR         7428359000            7.22
 7 RS         6415590842            6.23
 8 GO         4136086864            4.02
 9 SC         3922423937            3.81
10 BA         3595007469            3.49
# ... with 18 more rows

Vamos ver como ficam as descritivas:

Parâmetro Valor (TotalExp_UF)
Mínimo: 1.3547392
Média: 367.5111572
Máximo: 1928.674188

Determino o intervalo adequado de classe conforme Regra de Sturges:

k <- 1 + 3.322*log10(28)

round(k,digits = 0) # Numero ideal de classes a serem utilizadas
 6
amplitude <- (max(expuf$TotalExp_UF) - min(expuf$TotalExp_UF)) / k

amplitude #Tamanho do intervalo
 3318696620

Os intervalos de classe são obtidos então:

primclassmin <- min(expuf$TotalExp_UF)
primclassmax <- (min(expuf$TotalExp_UF) + amplitude - 1)

segclassmin <- primclassmax +1
segclassmax <- (segclassmin + amplitude -1)

terclassmin <- segclassmax +1
terclassmax <- (terclassmin + amplitude -1)

quaclassmin <- terclassmax +1
quaclassmax <- (quaclassmin + amplitude -1)

quiclassmin <- quaclassmax +1
quiclassmax <- (quiclassmin + amplitude -1)

sexclassmin <- quiclassmax +1
sexclassmax <- (sexclassmin + amplitude -1)

Então determinamos os intervalos de classes. P. ex., a primeira classe vai de 13.547392 até 3332.244011. (Os valores foram divididos por 10000000 para facilitar a leitura)

Classe Intervalo
Primeira: de 1.3547392 até 333.2244011
Segunda: de 333.2244012 até 665.0940631
Terceira: de 665.0940632 até 996.9637251
Quarta: de 996.9637252 até 1328.8333871
Quinta: de 1328.8333872 até 1660.7030491
Sexta: de 1660.7030492 até 1992.5727111

Podemos também observar o novo dataset agrupado:

write.csv(expuf, "expuf.csv")

Renomeio o nome da coluna SG_UF_NCM pra fazer o join:

colnames(expuf)[1]<-"abbrev_state"

Vamos ver no mapa como fica. Inicialmente carrego as bibliotecas:

library(tmap)
library(sf)
library(leaflet)
library(tmaptools)
library(geobr)

uf<-read_state(code_state="all", showProgress = FALSE)

Agora faço a junção:

junta<-full_join(uf, expuf, by="abbrev_state")

Em seguida crio as categorias de classes pro mapa:

junta$categorias_em_dolares<-
  cut(junta$TotalExp_UF,
      breaks=c(0, 3332244011, 6650940631, 9969637251, 13288333871, 16607030491, 19925727111),
  labels=c("de 13547392 a 3332244011",
           "de 3332244012 a 6650940631",
           "de 6650940632 a 9969637251", 
           "de 6650940633 a 13288333871",
           "de 13288333872 a 16607030491",
           "de 16607030492 a 19925727111"))

Então geramos o mapa:

library(ggspatial) #pacote para carregar a escala no mapa (funcao annotation_scale)

ggplot(junta)+
  geom_sf(aes(fill=categorias_em_dolares))+
  scale_fill_manual(values=c('#999999','#F3D4D2','#E9A8A2','#E9635A','#C41617','#6A0002'))+
  annotation_scale(location = "br", height = unit(0.2,"cm"))+
  annotation_north_arrow(location="tr", style = north_arrow_nautical, height=unit(1.5,"cm"), width=unit(1.5,"cm"))+
  labs(x = "Longitude", y = "Latitude", title = "Mapa por estado do fluxo de exportações (em US$ FOB)")

Ou então de um modo mais simples gero um mapa com as classes de cores graduada de modo automático pelo R.

tm_shape(junta)+
  tm_polygons("TotalExp_UF", id="abbrev_state", palette = "Reds")

Tento criar um mapa interativo:

tmap_mode("view")
tmap_last()
str(junta) #Soh uma olhada nos dados que foram juntados
## Classes 'sf' and 'data.frame':   28 obs. of  9 variables:
##  $ code_state           : num  11 12 13 14 15 16 17 21 22 23 ...
##  $ abbrev_state         : chr  "RO" "AC" "AM" "RR" ...
##  $ name_state           : chr  "Rondônia" "Acre" "Amazonas" "Roraima" ...
##  $ code_region          : num  1 1 1 1 1 1 1 2 2 2 ...
##  $ name_region          : chr  "Norte" "Norte" "Norte" "Norte" ...
##  $ TotalExp_UF          : num  837405995 13547392 375701579 79615524 11265073687 ...
##  $ ExpUFpercentual      : num  0.8138 0.0132 0.3651 0.0774 10.9473 ...
##  $ geom                 :sfc_MULTIPOLYGON of length 28; first list element: List of 1
##   ..$ :List of 1
##   .. ..$ : num [1:3230, 1:2] -63.3 -62.9 -62.9 -62.8 -62.8 ...
##   ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
##  $ categorias_em_dolares: Factor w/ 6 levels "de 13547392 a 3332244011",..: 1 1 1 1 4 1 1 1 1 1 ...
##  - attr(*, "sf_column")= chr "geom"
##  - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA
##   ..- attr(*, "names")= chr [1:8] "code_state" "abbrev_state" "name_state" "code_region" ...

Um outro modelo de mapa no R pode ser gerado usando:

#library(viridis)
#junta %>% 
#   ggplot(aes(fill = TotalExp_UF), color = "black") +
#    geom_sf() + 
#    scale_fill_viridis(name = "Exportações por UF", direction = -1)

Uma visualização de mapa mais adequada pode ser obtida com uma certa interatividade. Primeiro gero os centróides dos pontos no mapa:

coord_pontos <- junta %>% 
                  mutate(ExpUFpercentual = TotalExp_UF/sum(TotalExp_UF,na.rm = FALSE)) %>% 
                  st_centroid()
## Warning in st_centroid.sf(.): st_centroid assumes attributes are constant over
## geometries of x
## Warning in st_centroid.sfc(st_geometry(x), of_largest_polygon =
## of_largest_polygon): st_centroid does not give correct centroids for longitude/
## latitude data
#ggplot(junta)+ 
#  geom_sf() + 
#  geom_sf(data = coord_pontos, aes(size = ExpUFpercentual), col = "blue", alpha = .65,
#          show.legend = "point") + 
#  scale_size_continuous(name = "Exportações UF/US$ 1 MIlhão")

Em seguida geramos o mapa:

data.frame(st_coordinates(coord_pontos), 
           ExpUFpercentual = coord_pontos$ExpUFpercentual, 
           UF = coord_pontos$abbrev_state) %>% 
  leaflet() %>% 
    addTiles() %>%
    addCircleMarkers(~ X, ~ Y,
                     label = ~ as.character(paste0(UF, ": ", round(ExpUFpercentual*100,digits = 2), "%")),
                     labelOptions = labelOptions(textsize = "13px"),
                     radius = ~ ExpUFpercentual*100,
                     fillOpacity = 0.5)
## Warning in validateCoords(lng, lat, funcName): Data contains 1 rows with either
## missing or invalid lat/lon values and will be ignored

Podemos ver que tipo de produto cada estado mais exporta:

epufncm<-exp%>%
  group_by(SG_UF_NCM, CO_NCM)%>%
  summarise(TotExpUFNCM = sum(VL_FOB))

arrange(epufncm, desc(TotExpUFNCM))
# A tibble: 33,608 x 3
# Groups:   SG_UF_NCM [28]
   SG_UF_NCM   CO_NCM TotExpUFNCM
   <chr>        <int>       <dbl>
 1 RJ        27090010  8903993400
 2 PA        26011100  8266592251
 3 MG        26011100  5206737798
 4 MT        12019000  4067046892
 5 SP        17011400  1973864555
 6 MT        10059010  1954681983
 7 MG         9011110  1938188505
 8 PR        12019000  1722647522
 9 GO        12019000  1523146313
10 RS        12019000  1399094032
# ... with 33,598 more rows

Preciso substituir a coluna de códigos do NCM pelo nomes, para vermos o primeiro produto mais exportado por UF:

epufncm <- left_join(epufncm, ncm %>%
                             select(CO_NCM, NO_NCM_POR), by = c("CO_NCM" = "CO_NCM"))%>%
  select(-CO_NCM)

arrange(epufncm, desc(TotExpUFNCM))
# A tibble: 33,608 x 3
# Groups:   SG_UF_NCM [28]
   SG_UF_NCM TotExpUFNCM NO_NCM_POR                                             
   <chr>           <dbl> <chr>                                                  
 1 RJ         8903993400 Óleos brutos de petróleo                               
 2 PA         8266592251 Minérios de ferro e seus concentrados, exceto as pirit~
 3 MG         5206737798 Minérios de ferro e seus concentrados, exceto as pirit~
 4 MT         4067046892 Soja, mesmo triturada, exceto para semeadura           
 5 SP         1973864555 Outros açúcares de cana                                
 6 MT         1954681983 Milho em grão, exceto para semeadura                   
 7 MG         1938188505 Café não torrado, não descafeinado, em grão            
 8 PR         1722647522 Soja, mesmo triturada, exceto para semeadura           
 9 GO         1523146313 Soja, mesmo triturada, exceto para semeadura           
10 RS         1399094032 Soja, mesmo triturada, exceto para semeadura           
# ... with 33,598 more rows

Caso queiramos ver quais foram os produtos exportados pelo estado do Paraná nesse ano, fazemos:

epufncmPR <- epufncm%>%
  filter(SG_UF_NCM == "PR")

arrange(epufncmPR, desc(TotExpUFNCM))

   SG_UF_NCM TotExpUFNCM NO_NCM_POR                                             
   <chr>           <dbl> <chr>                                                  
 1 PR         1722647522 Soja, mesmo triturada, exceto para semeadura           
 2 PR          940667677 Pedaços e miudezas, comestíveis de galos/galinhas, con~
 3 PR          413767973 Bagaços e outros resíduos sólidos, da extração do óleo~
 4 PR          243443337 Carnes de galos/galinhas, não cortadas em pedaços, con~
 5 PR          235820543 Outros açúcares de cana                                
 6 PR          200321945 Outras madeiras compensadas, constituídas exclusivamen~
 7 PR          181388568 Automóveis com motor explosão, 1500 < cm3 <= 3000, até~
 8 PR          162379992 Milho em grão, exceto para semeadura                   
 9 PR          148338932 Pastas químicas de madeira, à soda ou ao sulfato, exce~
10 PR          146457577 Outros papéis e cartões dos tipos utilizados para escr~
# ... with 3,667 more rows

Agregando por país de destino

Baixo os dados dos países:

#paisesdwnld<-download.file("http://www.mdic.gov.br/balanca/bd/tabelas/PAIS.csv","paises.csv")
paises <- read.csv("paises.csv", sep = ";", encoding = "latin1")

glimpse(paises)
Rows: 281
Columns: 6
$ CO_PAIS       <int> 0, 13, 15, 17, 20, 23, 25, 31, 37, 40, 41, 42, 43, 47...
$ CO_PAIS_ISON3 <int> 898, 4, 248, 8, 724, 276, 278, 854, 20, 24, 660, 10, ...
$ CO_PAIS_ISOA3 <chr> "ZZZ", "AFG", "ALA", "ALB", "ESP", "DEU", "DEU", "BFA...
$ NO_PAIS       <chr> "Não Definido", "Afeganistão", "Aland, Ilhas", "Albân...
$ NO_PAIS_ING   <chr> "Not defined", "Afghanistan", "Aland Islands", "Alban...
$ NO_PAIS_ESP   <chr> "No definido", "Afganistan", "Alans, Islas", "Albania...

Então agrupo as exportações (em US$ FOB) por NCM: (O agrupamento é necessário por uma questão de limitação de processamento e memória)

#agrupa exp por pais
exppais<-exp%>%
  group_by(CO_PAIS)%>%
  summarise(Total_PAIS = sum(VL_FOB))

arrange(exppais, desc(Total_PAIS))
# A tibble: 237 x 2
   CO_PAIS  Total_PAIS
     <int>       <dbl>
 1     160 36894210361
 2     249 10140370057
 3      63  3869963440
 4     573  3286657344
 5     399  2266965970
 6     149  1942028652
 7      23  1872694108
 8     158  1849402628
 9     245  1837223178
10     493  1779008228
# ... with 227 more rows

Caso os nomes dos produtos pelo nome do pais de destino:

library(tidyverse)
exppais <- left_join(exppais, paises %>%
                             select(CO_PAIS, NO_PAIS), by = c("CO_PAIS" = "CO_PAIS"))%>%
                             mutate(TotExpPais = exppais$Total_PAIS)

glimpse(exppais)
Rows: 237
Columns: 4
$ CO_PAIS    <int> 13, 15, 17, 23, 31, 37, 40, 41, 42, 43, 53, 59, 63, 64, ...
$ Total_PAIS <dbl> 10453006, 140, 21394609, 1872694108, 3166082, 17964, 155...
$ NO_PAIS    <chr> "Afeganistão", "Aland, Ilhas", "Albânia", "Alemanha", "B...
$ TotExpPais <dbl> 10453006, 140, 21394609, 1872694108, 3166082, 17964, 155...
head(exppais)
# A tibble: 6 x 4
  CO_PAIS Total_PAIS NO_PAIS      TotExpPais
    <int>      <dbl> <chr>             <dbl>
1      13   10453006 Afeganistão    10453006
2      15        140 Aland, Ilhas        140
3      17   21394609 Albânia        21394609
4      23 1872694108 Alemanha     1872694108
5      31    3166082 Burkina Faso    3166082
6      37      17964 Andorra           17964

Vamos ver como fica a classificação:

exppais<-exppais%>%
  select(-Total_PAIS)

arrange(exppais,desc(TotExpPais))
# A tibble: 237 x 3
   CO_PAIS NO_PAIS                  TotExpPais
     <int> <chr>                         <dbl>
 1     160 China                   36894210361
 2     249 Estados Unidos          10140370057
 3      63 Argentina                3869963440
 4     573 Países Baixos (Holanda)  3286657344
 5     399 Japão                    2266965970
 6     149 Canadá                   1942028652
 7      23 Alemanha                 1872694108
 8     158 Chile                    1849402628
 9     245 Espanha                  1837223178
10     493 México                   1779008228
# ... with 227 more rows

Podemos visualizar quais os principais destinos de nossas exportações nesse ano projetando um mapa. Primeiramente eu busco uma tabela contendo os dados de latitudes e longitudes dos países:

latlong<- read.csv(file="https://raw.githubusercontent.com/rhozon/datasets/master/isoa3paises.csv", head=TRUE, sep=";")

str(latlong)
'data.frame':   249 obs. of  5 variables:
 $ ISOA3    : chr  "ABW" "AFG" "AGO" "AIA" ...
 $ Country  : chr  "Aruba" "Afghanistan" "Angola" "Anguilla" ...
 $ latitude : num  12.5 33.9 -11.2 18.2 NA ...
 $ longitude: num  -70 67.7 17.9 -63.1 NA ...
 $ COD_PAIS : int  65 13 40 41 15 17 37 237 63 64 ...

Renomeio as colunas de latitude e longitude:

colnames(latlong)[3]<-"lat"
colnames(latlong)[4]<-"long"
colnames(latlong)[5]<-"CO_PAIS"

glimpse(latlong)
Rows: 249
Columns: 5
$ ISOA3   <chr> "ABW", "AFG", "AGO", "AIA", "ALA", "ALB", "AND", "ARE", "AR...
$ Country <chr> "Aruba", "Afghanistan", "Angola", "Anguilla", "Åland Island...
$ lat     <dbl> 12.521110, 33.939110, -11.202692, 18.220554, NA, 41.153332,...
$ long    <dbl> -69.968338, 67.709953, 17.873887, -63.068615, NA, 20.168331...
$ CO_PAIS <int> 65, 13, 40, 41, 15, 17, 37, 237, 63, 64, 691, 42, 781, 43, ...

Faço um join com a tabela de exportações por país:

exppais <- left_join(exppais, paises %>%
                             select(CO_PAIS, CO_PAIS), by = c("CO_PAIS" = "CO_PAIS"))

str(exppais)
tibble [237 x 3] (S3: tbl_df/tbl/data.frame)
 $ CO_PAIS   : int [1:237] 13 15 17 23 31 37 40 41 42 43 ...
 $ NO_PAIS   : chr [1:237] "Afeganistão" "Aland, Ilhas" "Albânia" "Alemanha" ...
 $ TotExpPais: num [1:237] 10453006 140 21394609 1872694108 3166082 ...

Também precisamos inserir o código ISOA3 dos nomes dos países:

exppais<- left_join(exppais, latlong %>%
                      select(CO_PAIS, ISOA3), by = c("CO_PAIS" = "CO_PAIS"))
                    
glimpse(exppais)                    
Rows: 237
Columns: 4
$ CO_PAIS    <int> 13, 15, 17, 23, 31, 37, 40, 41, 42, 43, 53, 59, 63, 64, ...
$ NO_PAIS    <chr> "Afeganistão", "Aland, Ilhas", "Albânia", "Alemanha", "B...
$ TotExpPais <dbl> 10453006, 140, 21394609, 1872694108, 3166082, 17964, 155...
$ ISOA3      <chr> "AFG", "ALA", "ALB", "DEU", "BFA", "AND", "AGO", "AIA", ...

Em seguida a latitude

exppais<- left_join(exppais, latlong %>%
                      select(CO_PAIS, lat), by = c("CO_PAIS" = "CO_PAIS"))
                    
glimpse(exppais)  
Rows: 237
Columns: 5
$ CO_PAIS    <int> 13, 15, 17, 23, 31, 37, 40, 41, 42, 43, 53, 59, 63, 64, ...
$ NO_PAIS    <chr> "Afeganistão", "Aland, Ilhas", "Albânia", "Alemanha", "B...
$ TotExpPais <dbl> 10453006, 140, 21394609, 1872694108, 3166082, 17964, 155...
$ ISOA3      <chr> "AFG", "ALA", "ALB", "DEU", "BFA", "AND", "AGO", "AIA", ...
$ lat        <dbl> 33.93911, NA, 41.15333, 51.16569, 12.23833, 42.54624, -1...

e também a longitude

exppais<- left_join(exppais, latlong %>%
                      select(CO_PAIS, long), by = c("CO_PAIS" = "CO_PAIS"))
                    
glimpse(exppais)  
Rows: 237
Columns: 6
$ CO_PAIS    <int> 13, 15, 17, 23, 31, 37, 40, 41, 42, 43, 53, 59, 63, 64, ...
$ NO_PAIS    <chr> "Afeganistão", "Aland, Ilhas", "Albânia", "Alemanha", "B...
$ TotExpPais <dbl> 10453006, 140, 21394609, 1872694108, 3166082, 17964, 155...
$ ISOA3      <chr> "AFG", "ALA", "ALB", "DEU", "BFA", "AND", "AGO", "AIA", ...
$ lat        <dbl> 33.93911, NA, 41.15333, 51.16569, 12.23833, 42.54624, -1...
$ long       <dbl> 67.709953, NA, 20.168331, 10.451526, -1.561593, 1.601554...

Vamos ver se o mapa com o leaflet sai:

library(leaflet)

# Cria as labels dos popups
make_label <- function(pais, vlrexportado) {
  txt <- stringr::str_glue(
    "<b>País</b>: {pais}<br>",
    "<b>Exportações</b>: {vlrexportado}"
  )
  htmltools::HTML(txt)
}


mapaleaflet<-exppais %>% 
  mutate(lab = map2(NO_PAIS, TotExpPais, make_label)) %>%
  leaflet() %>% 
  addTiles() %>% 
  addMarkers(lng = ~long, lat = ~lat, popup = ~lab,
             clusterOptions = markerClusterOptions())
## Warning in validateCoords(lng, lat, funcName): Data contains 20 rows with either
## missing or invalid lat/lon values and will be ignored
mapaleaflet

Agregando por via

Por qual modal o fluxo financeiro da pauta de exportações tupiniquim é mais proeminente ? Será que o rodoviário (mais caro) é também o mais eficiente ?

Baixo os dados descritores dos tipos de via (dicionário):

#viadwnld<-download.file("http://www.mdic.gov.br/balanca/bd/tabelas/VIA.csv","via.csv")
via <- read.csv("via.csv", sep = ";", encoding = "latin1")

glimpse(via)
Rows: 17
Columns: 2
$ CO_VIA <int> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 99, 13, 11, 15, 14, 12
$ NO_VIA <chr> "VIA NAO DECLARADA", "MARITIMA", "FLUVIAL", "LACUSTRE", "AER...

Então agrupo as exportações (em US$ FOB) por via: (O agrupamento é necessário por uma questão de limitação de processamento e memória)

#agrupa exp por pais
expvia<-exp%>%
  group_by(CO_VIA)%>%
  summarise(Total_VIA = sum(VL_FOB))

arrange(expvia, desc(Total_VIA))
# A tibble: 13 x 2
   CO_VIA   Total_VIA
    <int>       <dbl>
 1      1 83079210580
 2      0 10221051606
 3      7  4768463025
 4      9   162597122
 5      2   111992081
 6      6    37076207
 7     15     9769700
 8     12     4578848
 9      3     3336455
10      8     1956714
11     13        3137
12     14        1016
13      4          NA

Caso os nomes das vias:

library(tidyverse)
expvia <- left_join(expvia, via %>%
                             select(CO_VIA, NO_VIA), by = c("CO_VIA" = "CO_VIA"))%>%
                             mutate(TotExpVia = expvia$Total_VIA)

glimpse(expvia)
Rows: 13
Columns: 4
$ CO_VIA    <int> 0, 1, 2, 3, 4, 6, 7, 8, 9, 12, 13, 14, 15
$ Total_VIA <dbl> 10221051606, 83079210580, 111992081, 3336455, NA, 3707620...
$ NO_VIA    <chr> "VIA NAO DECLARADA", "MARITIMA", "FLUVIAL", "LACUSTRE", "...
$ TotExpVia <dbl> 10221051606, 83079210580, 111992081, 3336455, NA, 3707620...
head(expvia)
# A tibble: 6 x 4
  CO_VIA   Total_VIA NO_VIA              TotExpVia
   <int>       <dbl> <chr>                   <dbl>
1      0 10221051606 VIA NAO DECLARADA 10221051606
2      1 83079210580 MARITIMA          83079210580
3      2   111992081 FLUVIAL             111992081
4      3     3336455 LACUSTRE              3336455
5      4          NA AEREA                      NA
6      6    37076207 FERROVIARIA          37076207

Vamos ver como fica a classificação:

expvia<-expvia%>%
  select(-Total_VIA)

arrange(expvia,desc(TotExpVia))
# A tibble: 13 x 3
   CO_VIA NO_VIA                        TotExpVia
    <int> <chr>                             <dbl>
 1      1 MARITIMA                    83079210580
 2      0 VIA NAO DECLARADA           10221051606
 3      7 RODOVIARIA                   4768463025
 4      9 MEIOS PROPRIOS                162597122
 5      2 FLUVIAL                       111992081
 6      6 FERROVIARIA                    37076207
 7     15 VICINAL FRONTEIRICO             9769700
 8     12 EM MAOS                         4578848
 9      3 LACUSTRE                        3336455
10      8 CONDUTO/REDE DE TRANSMISSAO     1956714
11     13 POR REBOQUE                        3137
12     14 DUTOS                              1016
13      4 AEREA                                NA

Agregando por COD_URF

Baixo os dados descritores dos tipos de códigos na unidade da Receita Federal (dicionário):

#urfdwnld<-download.file("http://www.mdic.gov.br/balanca/bd/tabelas/URF.csv","urf.csv")
urf <- read.csv("urf.csv", sep = ";", encoding = "latin1")

glimpse(urf)
Rows: 276
Columns: 2
$ CO_URF <int> 510353, 710251, 1010351, 1017504, 1017505, 510352, 317903, 9...
$ NO_URF <chr> "0510353 - IRF ILHEUS", "0710251 - IRF CAMPOS DOS GOYTACAZES...

Então agrupo as exportações (em US$ FOB) por código da receita federal: (O agrupamento é necessário por uma questão de limitação de processamento e memória)

#agrupa exp por pais
expurf<-exp%>%
  group_by(CO_URF)%>%
  summarise(Total_URF = sum(VL_FOB))

arrange(expurf, desc(Total_URF))
# A tibble: 75 x 2
    CO_URF   Total_URF
     <int>       <dbl>
 1  817800 29400112261
 2  317903 11891083566
 3  717800  9309642505
 4  917800  8169399453
 5 1017700  4940027748
 6  727600  4694864039
 7  817600  3381198622
 8  217800  3168511672
 9  710251  3125094939
10  927800  3033321281
# ... with 65 more rows

Caso os nomes das URFs:

library(tidyverse)
expurf <- left_join(expurf, urf %>%
                             select(CO_URF, NO_URF), by = c("CO_URF" = "CO_URF"))%>%
                             mutate(TotExpUrf = expurf$Total_URF)

glimpse(expurf)
Rows: 75
Columns: 4
$ CO_URF    <int> 117600, 130151, 140100, 147600, 147700, 147800, 147852, 2...
$ Total_URF <dbl> 3842823, 412942, 13318, 467842338, 16197833, 46812453, 51...
$ NO_URF    <chr> "0117600 - AEROPORTO INTERNACIONAL DE BRASILIA", "0130151...
$ TotExpUrf <dbl> 3842823, 412942, 13318, 467842338, 16197833, 46812453, 51...
head(expurf)
# A tibble: 6 x 4
  CO_URF Total_URF NO_URF                                        TotExpUrf
   <int>     <dbl> <chr>                                             <dbl>
1 117600   3842823 0117600 - AEROPORTO INTERNACIONAL DE BRASILIA   3842823
2 130151    412942 0130151 - CACERES                                412942
3 140100     13318 0140100 - CAMPO GRANDE                            13318
4 147600 467842338 0147600 - ALF - CORUMBÁ                       467842338
5 147700  16197833 0147700 - ALF - MUNDO NOVO                     16197833
6 147800  46812453 0147800 - ALF - PONTA PORÃ                     46812453

Vamos ver como fica a classificação:

expurf<-expurf%>%
  select(-Total_URF)

arrange(expurf,desc(TotExpUrf))
# A tibble: 75 x 3
    CO_URF NO_URF                                                     TotExpUrf
     <int> <chr>                                                          <dbl>
 1  817800 0817800 - PORTO DE SANTOS                                29400112261
 2  317903 0317903 - IRF SAO LUIS                                   11891083566
 3  717800 0717800 - PORTO DE ITAGUAI                                9309642505
 4  917800 0917800 - PORTO DE PARANAGUA                              8169399453
 5 1017700 1017700 - PORTO DE RIO GRANDE                             4940027748
 6  727600 0727600 - PORTO DE VITORIA                                4694864039
 7  817600 0817600 - AEROPORTO INTERNACIONAL DE SAO PAULO/GUARULHOS  3381198622
 8  217800 0217800 - ALF - BELÉM                                     3168511672
 9  710251 0710251 - IRF CAMPOS DOS GOYTACAZES                       3125094939
10  927800 0927800 - ITAJAI                                          3033321281
# ... with 65 more rows

Visualização da base de dados completa


(Abra no modo tela inteira)


Referências

CRAN The Comprehensive R Archive Network. Disponível em < https://cran.r-project.org/ >

Ministério da Defesa Indústria e Comércio Exterior. Disponível em < http://www.mdic.gov.br/index.php/comercio-exterior/estatisticas-de-comercio-exterior/base-de-dados-do-comercio-exterior-brasileiro-arquivos-para-download >